package com.joe.runaway.controller;

import com.joe.runaway.config.ai.LangChain4JProvider;
import com.joe.runaway.vo.ChatReq;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;


@Slf4j
@RestController
@RequestMapping(value = "stream")
public class StreamChatController {

    @Resource
    LangChain4JProvider langChain4JProvider;

//    @PostMapping(value = "conversation", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Object streamChat(@RequestBody ChatReq req){
        if (req.getStream()){
            return "回复：" + req.getMessage();
        }else {
            return streamChat(req.getMessage());
        }
    }

    /**
     * deepseek对话-流式响应
     *
     * @param req
     * @return
     */
    @PostMapping(value = "conversation", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
//    @PostMapping(value = "streamingChat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> deepSeekStreamingChat(@RequestBody ChatReq req) {
        return streamChat(req.getMessage());
    }

    private Flux<String> streamChat(String message){
        return Flux.create(fluxSink -> {
            langChain4JProvider.getQwenStreamingChatModel().chat(message, new StreamingChatResponseHandler() {
                @Override
                public void onPartialResponse(String callback) {
                    // 将部分响应写入 Flux
                    fluxSink.next(callback);
                }

                @Override
                public void onCompleteResponse(ChatResponse chatResponse) {
                    // 处理完成响应
                    System.out.println("onCompleteResponse: " + chatResponse);
                    fluxSink.complete();
                }

                @Override
                public void onError(Throwable throwable) {
                    fluxSink.error(throwable);
                }
            });
        });
    }

}
